import React, {Component} from 'react'
import {Spin} from 'antd'
import Article from './Article'
import styles from './index.less'
import {get, parseUrl} from '../../utils'
import {getLocale} from 'umi/locale'

import 'rc-drawer/assets/index.css'
import marked from 'marked'
import hljs from 'highlight.js/lib/highlight'
import javascript from 'highlight.js/lib/languages/javascript'
import php from 'highlight.js/lib/languages/php'
import go from 'highlight.js/lib/languages/go'
import python from 'highlight.js/lib/languages/python'
import nginx from 'highlight.js/lib/languages/nginx'
import sql from 'highlight.js/lib/languages/sql'
import lua from 'highlight.js/lib/languages/lua'
import bash from 'highlight.js/lib/languages/bash'
import css from 'highlight.js/lib/languages/css'
import java from 'highlight.js/lib/languages/java'
import xml from 'highlight.js/lib/languages/xml'

hljs.registerLanguage('javascript', javascript)
hljs.registerLanguage('php', php)
hljs.registerLanguage('go', go)
hljs.registerLanguage('python', python)
hljs.registerLanguage('nginx', nginx)
hljs.registerLanguage('sql', sql)
hljs.registerLanguage('lua', lua)
hljs.registerLanguage('bash', bash)
hljs.registerLanguage('css', css)
hljs.registerLanguage('java', java)
hljs.registerLanguage('xml', xml)

import 'highlight.js/styles/vs.css'
import {connect} from 'dva'

const SanitizeState = require('marked-sanitizer-github').default

// Get reference
let toc = []
let renderer = new marked.Renderer()

// Override function
renderer.heading = function (text, level) {
  if (level === 1 || level > 3 || text.indexOf('<a href') !== -1) {
    return `
      <h${level}>
        ${text}
      </h${level}>`
  }

  let anchor = text.toLowerCase().replace(' ', '-')
  toc.push({
    anchor: anchor,
    level: level,
    text: text,
  })

  return `
    <h${level} id="${anchor}">
      ${text}<a name="${anchor}" class="anchor" href="#${anchor}">#</a>      
    </h${level}>`
}

renderer.image = function (href, title) {
  title = title || ''

  let className = get(parseUrl(href), 'class', '')
  if (className) {
    className = `class="${className}"`
  }

  return `<img src="${href}" ${className} title="${title}" onclick="window.g_app._store.dispatch({type:'lightbox/show',payload:{isOpen:true,src:'${href}'}})"/>`
}
renderer.flowIndex = 0
renderer.diagramFlows = []
renderer.diagramMermaid = false
renderer.code = function (code, lang, escaped) {
  if (lang === 'flow') {
    let id = 'flowchart-' + (++renderer.flowIndex)
    let ele = `<div id ='${id}' class="flowchart" data-source="${encodeURI(code)}"></div>`
    renderer.diagramFlows.push({id, code})
    return ele
  }

  if (lang === 'mermaid') {
    let ele = `<div class="mermaid">${code}</div>`
    renderer.diagramMermaid = true
    return ele
  }

  return marked.Renderer.prototype.code.call(this, code, lang, escaped)
}

renderer.link = (href, title, text) => {
  if (href.startsWith('#')) {
    return `<a title="${title}" href="${href}">${text}</a>`
  } else if (href.startsWith('/')) {
    return `<a title="${title}" onclick="window.g_app._store.dispatch({type: 'content/redirect', payload: '${href}'})">${text}</a>`
  } else {
    let target = get(parseUrl(href), 'target', '_blank')
    if (target) {
      target = `target="${target}"`
    }
    return `<a title="${title}" href="${href}" ${target}>${text}</a>`
  }
}

const state = new SanitizeState()
marked.setOptions({
  highlight: function (code, lang) {
    if (!lang) {
      return code
    }
    return hljs.highlightAuto(code).value
  },
  sanitize: true,
  sanitizer: state.getSanitizer(),
})

@connect(({content}) => ({content: content.content.data}))
export default class MainContent extends Component {

  state = {
    loading: false,
  }

  componentDidMount() {
    const {dispatch} = this.props
    dispatch({type: 'content/getContentAction'})
  }

  renderMarkdown = (text, cb) => {
    toc = []
    let html = marked(text, {breaks: true, renderer: renderer})
    let tocHTML = ''
    if (text.indexOf('[TOC]') !== -1) {
      tocHTML = '<ul class="toc">'
      toc.forEach(function (entry) {
        tocHTML += `<li><a href="#${entry.anchor}" >${entry.text}<a></li>`
      })
      tocHTML += '</ul>'
      html = html.replace('[TOC]', '')
    }

    //采用定时器，这样可以最大限度的保证不会刷新太多次
    //如果有回调，则预先将HTML放置到容器中
    if (cb) {
      document.querySelector('#hide_markdown').innerHTML = html
    }

    setTimeout(function () {
      for (let i = 0; i < renderer.diagramFlows.length; i++) {
        let v = renderer.diagramFlows.pop()
        if (document.querySelector('#' + v.id)) {
          let diagram = flowchart.parse(v.code)
          diagram.drawSVG(v.id)
        }
      }

      if (renderer.diagramMermaid) {
        renderer.diagramMermaid = false
        mermaid.init({noteMargin: 0}, '.mermaid')
      }
      cb && cb({toc: tocHTML, html})
    }, 50)
    return {
      toc: tocHTML,
      html,
    }
  }

  render() {
    const {loading} = this.state
    const {content, ...otherProps} = this.props
    const {location: {query: {page = 'home'}}} = this.props
    const languageIndex = 'en-US' === getLocale() ? page : `${page}.${getLocale()}`
    const text = get(content, languageIndex, '') || get(content, page, '') || ''
    return (
      <Spin spinning={loading}>
        <section className='main-container'>
          <Article
            {...otherProps}
            currentArticle={{content: text}}
            loading={loading}
            renderMarkdown={this.renderMarkdown}
          />
        </section>
      </Spin>
    )
  }
}
